
package com.kugou.game.sdk.download;

import com.kugou.download.DownloadFile;
import com.kugou.download.FileDownloader;
import com.kugou.framework.db.BaseDbTableOperator;
import com.kugou.framework.db.IContentObserver;
import com.kugou.framework.download.DownloadTable;
import com.kugou.game.sdk.core.SDKControler;

import android.content.ContentValues;
import android.content.Context;
import android.database.Cursor;
import android.database.sqlite.SQLiteDatabase;

import java.util.ArrayList;
import java.util.List;

/**
 * 描述:下载表操作类
 * 
 * @author chenys
 * @since 2013-12-18 下午5:10:25
 */
public class DownloadOperator extends BaseDbTableOperator<DownloadFile> {

    private static DownloadOperator mDownloadOperator;

    private DownloadOperator(Context context) {
        super(context);
    }

    public static synchronized DownloadOperator getInstance() {
        if (mDownloadOperator == null) {
            mDownloadOperator = new DownloadOperator(SDKControler.getContext());
        }
        return mDownloadOperator;
    }

    private IContentObserver<DownloadFile> mContentObserver;

    @Override
    protected SQLiteDatabase getReadableDatabase() {
        return SDKDbHelper.getInstance(getContext()).getReadableDatabase();
    }

    @Override
    protected SQLiteDatabase getWritableDatabase() {
        return SDKDbHelper.getInstance(getContext()).getWritableDatabase();
    }

    @Override
    public long insert(DownloadFile file) {
        ContentValues cv = new ContentValues();
        cv.put(DownloadTable.RES_URL, file.getResUrl());
        cv.put(DownloadTable.FILE_PATH, file.getFilePath());
        cv.put(DownloadTable.FILE_NAME, file.getFileName());
        cv.put(DownloadTable.FILE_SIZE, file.getFileSize());
        cv.put(DownloadTable.MIME_TYPE, file.getMimeType());
        cv.put(DownloadTable.HAVE_READ, file.getHaveRead());
        cv.put(DownloadTable.STATE, file.getState());
        cv.put(DownloadTable.KEY, file.getKey());
        cv.put(DownloadTable.CLASSID, file.getClassId());
        cv.put(DownloadTable.IS_DELETE, file.isDelete());
        cv.put(DownloadTable.EXT1, file.getExt1());
        cv.put(DownloadTable.EXT2, file.getExt2());
        cv.put(DownloadTable.EXT3, file.getExt3());
        cv.put(DownloadTable.EXT4, file.getExt4());
        cv.put(DownloadTable.EXT5, file.getExt5());
        cv.put(DownloadTable.EXT6, file.getExt6());
        cv.put(DownloadTable.EXT7, file.getExt7());
        cv.put(DownloadTable.EXT8, file.getExt8());
        cv.put(DownloadTable.EXT9, file.getExt9());
        cv.put(DownloadTable.EXT10, file.getExt10());
        cv.put(DownloadTable.EXT11, file.getExt11());
        cv.put(DownloadTable.EXT12, file.getExt12());
        cv.put(DownloadTable.EXT13, file.getExt13());
        cv.put(DownloadTable.EXT14, file.getExt14());
        cv.put(DownloadTable.EXT15, file.getExt15());
        cv.put(DownloadTable.EXT16, file.getExt16());

        long id = getWritableDatabase().insert(DownloadTable.TABLE_NAME, null, cv);
        if (mContentObserver != null) {
            mContentObserver.onChange(file, IContentObserver.STATE_INSERT);
        }
        return id;
    }

    @Override
    public long update(ContentValues cv, String selection, String[] selectionArgs) {
        long id = getWritableDatabase().update(DownloadTable.TABLE_NAME, cv, selection,
                selectionArgs);
        if (mContentObserver != null) {
            mContentObserver.onChange(null, IContentObserver.STATE_UPDATE);
        }
        return id;
    }

    @Override
    public long delete(String selection, String[] selectionArgs) {
        long id = getWritableDatabase().delete(DownloadTable.TABLE_NAME, selection, selectionArgs);
        if (mContentObserver != null) {
            mContentObserver.onChange(null, IContentObserver.STATE_DELETE);
        }
        return id;
    }

    @Override
    public List<DownloadFile> query(String selection, String[] selectionArgs, String orderby) {
        Cursor c = getReadableDatabase().query(DownloadTable.TABLE_NAME, null, selection,
                selectionArgs, null, null, orderby);
        return getDownloadFileFromCursor(c);
    }

    @Override
    public List<DownloadFile> query(String selection, String[] selectionArgs, String orderby,
            int limit) {
        Cursor c = getReadableDatabase().query(DownloadTable.TABLE_NAME, null, selection,
                selectionArgs, null, null, orderby, String.valueOf(limit));
        return getDownloadFileFromCursor(c);
    }

    @Override
    public DownloadFile query(String selection, String[] selectionArgs) {
        List<DownloadFile> files = query(selection, selectionArgs, null);
        if (files != null && files.size() > 0) {
            return files.get(0);
        }
        return null;
    }

    @Override
    public int getCount(String selection, String[] selectionArgs) {
        String[] projection = {
            " count(*) "
        };
        Cursor c = getReadableDatabase().query(DownloadTable.TABLE_NAME, projection, selection,
                selectionArgs, null, null, DownloadTable.DEFAULT_SORT_ORDER);
        int count = 0;
        if (c != null) {
            if (c.moveToFirst()) {
                count = c.getInt(0);
            }
            c.close();
        }
        return count;
    }

    /**
     * 获取下载文件信息
     * 
     * @param c
     * @return
     */
    public static List<DownloadFile> getDownloadFileFromCursor(Cursor c) {
        if (c != null) {
            List<DownloadFile> files = new ArrayList<DownloadFile>(c.getCount());
            DownloadFile file = null;
            for (c.moveToFirst(); !c.isAfterLast(); c.moveToNext()) {
                file = new DownloadFile();
                file.setId(c.getLong(c.getColumnIndexOrThrow(DownloadTable._ID)));
                file.setResUrl(c.getString(c.getColumnIndexOrThrow(DownloadTable.RES_URL)));
                file.setFilePath(c.getString(c.getColumnIndexOrThrow(DownloadTable.FILE_PATH)));
                file.setFileName(c.getString(c.getColumnIndexOrThrow(DownloadTable.FILE_NAME)));
                file.setFileSize(c.getLong(c.getColumnIndexOrThrow(DownloadTable.FILE_SIZE)));
                file.setHaveRead(c.getLong(c.getColumnIndexOrThrow(DownloadTable.HAVE_READ)));
                file.setMimeType(c.getString(c.getColumnIndexOrThrow(DownloadTable.MIME_TYPE)));
                file.setState(c.getInt(c.getColumnIndexOrThrow(DownloadTable.STATE)));
                file.setKey(c.getString(c.getColumnIndexOrThrow(DownloadTable.KEY)));
                file.setClassId(c.getInt(c.getColumnIndexOrThrow(DownloadTable.CLASSID)));
                file.setDelete(c.getInt(c.getColumnIndexOrThrow(DownloadTable.IS_DELETE)));
                file.setExt1(c.getString(c.getColumnIndexOrThrow(DownloadTable.EXT1)));
                file.setExt2(c.getString(c.getColumnIndexOrThrow(DownloadTable.EXT2)));
                file.setExt3(c.getString(c.getColumnIndexOrThrow(DownloadTable.EXT3)));
                file.setExt4(c.getString(c.getColumnIndexOrThrow(DownloadTable.EXT4)));
                file.setExt5(c.getString(c.getColumnIndexOrThrow(DownloadTable.EXT5)));
                file.setExt6(c.getString(c.getColumnIndexOrThrow(DownloadTable.EXT6)));
                file.setExt7(c.getString(c.getColumnIndexOrThrow(DownloadTable.EXT7)));
                file.setExt8(c.getString(c.getColumnIndexOrThrow(DownloadTable.EXT8)));
                file.setExt9(c.getString(c.getColumnIndexOrThrow(DownloadTable.EXT9)));
                file.setExt10(c.getString(c.getColumnIndexOrThrow(DownloadTable.EXT10)));
                file.setExt11(c.getString(c.getColumnIndexOrThrow(DownloadTable.EXT11)));
                file.setExt12(c.getString(c.getColumnIndexOrThrow(DownloadTable.EXT12)));
                file.setExt13(c.getString(c.getColumnIndexOrThrow(DownloadTable.EXT13)));
                file.setExt14(c.getString(c.getColumnIndexOrThrow(DownloadTable.EXT14)));
                file.setExt15(c.getString(c.getColumnIndexOrThrow(DownloadTable.EXT15)));
                file.setExt16(c.getString(c.getColumnIndexOrThrow(DownloadTable.EXT16)));
                files.add(file);
            }
            c.close();
            return files;
        }
        return null;
    }

    public long update(DownloadFile file, String key) {
        String selection = DownloadTable.KEY + " = ? ";
        String[] selectionArgs = {
            key
        };
        ContentValues cv = new ContentValues();
        cv.put(DownloadTable.RES_URL, file.getResUrl());
        cv.put(DownloadTable.FILE_PATH, file.getFilePath());
        cv.put(DownloadTable.FILE_NAME, file.getFileName());
        cv.put(DownloadTable.FILE_SIZE, file.getFileSize());
        cv.put(DownloadTable.MIME_TYPE, file.getMimeType());
        cv.put(DownloadTable.HAVE_READ, file.getHaveRead());
        cv.put(DownloadTable.STATE, file.getState());
        cv.put(DownloadTable.CLASSID, file.getClassId());
        cv.put(DownloadTable.IS_DELETE, file.isDelete());
        cv.put(DownloadTable.EXT1, file.getExt1());
        cv.put(DownloadTable.EXT2, file.getExt2());
        cv.put(DownloadTable.EXT3, file.getExt3());
        cv.put(DownloadTable.EXT4, file.getExt4());
        cv.put(DownloadTable.EXT5, file.getExt5());
        cv.put(DownloadTable.EXT6, file.getExt6());
        cv.put(DownloadTable.EXT7, file.getExt7());
        cv.put(DownloadTable.EXT8, file.getExt8());
        cv.put(DownloadTable.EXT9, file.getExt9());
        cv.put(DownloadTable.EXT10, file.getExt10());
        cv.put(DownloadTable.EXT11, file.getExt11());
        cv.put(DownloadTable.EXT12, file.getExt12());
        cv.put(DownloadTable.EXT13, file.getExt13());
        cv.put(DownloadTable.EXT14, file.getExt14());
        cv.put(DownloadTable.EXT15, file.getExt15());
        cv.put(DownloadTable.EXT16, file.getExt16());
        return update(cv, selection, selectionArgs);
    }

    public long update(DownloadFile file, long id) {
        String selection = DownloadTable._ID + " = ? ";
        String[] selectionArgs = {
            String.valueOf(id)
        };
        ContentValues cv = new ContentValues();
        cv.put(DownloadTable.RES_URL, file.getResUrl());
        cv.put(DownloadTable.FILE_PATH, file.getFilePath());
        cv.put(DownloadTable.FILE_NAME, file.getFileName());
        cv.put(DownloadTable.FILE_SIZE, file.getFileSize());
        cv.put(DownloadTable.MIME_TYPE, file.getMimeType());
        cv.put(DownloadTable.HAVE_READ, file.getHaveRead());
        cv.put(DownloadTable.STATE, file.getState());
        cv.put(DownloadTable.CLASSID, file.getClassId());
        cv.put(DownloadTable.IS_DELETE, file.isDelete());
        cv.put(DownloadTable.EXT1, file.getExt1());
        cv.put(DownloadTable.EXT2, file.getExt2());
        cv.put(DownloadTable.EXT3, file.getExt3());
        cv.put(DownloadTable.EXT4, file.getExt4());
        cv.put(DownloadTable.EXT5, file.getExt5());
        cv.put(DownloadTable.EXT6, file.getExt6());
        cv.put(DownloadTable.EXT7, file.getExt7());
        cv.put(DownloadTable.EXT8, file.getExt8());
        cv.put(DownloadTable.EXT9, file.getExt9());
        cv.put(DownloadTable.EXT10, file.getExt10());
        cv.put(DownloadTable.EXT11, file.getExt11());
        cv.put(DownloadTable.EXT12, file.getExt12());
        cv.put(DownloadTable.EXT13, file.getExt13());
        cv.put(DownloadTable.EXT14, file.getExt14());
        cv.put(DownloadTable.EXT15, file.getExt15());
        cv.put(DownloadTable.EXT16, file.getExt16());
        return update(cv, selection, selectionArgs);
    }

    public long delete(String key) {
        String selection = DownloadTable.KEY + " = ? ";
        String[] selectionArgs = {
            key
        };
        return delete(selection, selectionArgs);
    }

    public long delete(long id) {
        String selection = DownloadTable._ID + " = ? ";
        String[] selectionArgs = {
            String.valueOf(id)
        };
        return delete(selection, selectionArgs);
    }

    public DownloadFile query(String key) {
        String selection = DownloadTable.KEY + " = ? ";
        String[] selectionArgs = {
            key
        };
        return query(selection, selectionArgs);
    }

    public DownloadFile query(long id) {
        String selection = DownloadTable._ID + " = ? ";
        String[] selectionArgs = {
            String.valueOf(id)
        };
        return query(selection, selectionArgs);
    }

    /**
     * 获取还没下载完成的任务列表
     * 
     * @return
     */
    public List<DownloadFile> getDownloadingFiles(int classId) {
        String selection = DownloadTable.STATE + " != " + FileDownloader.FINISH + " AND "
                + DownloadTable.CLASSID + " = " + classId + " AND " + DownloadTable.IS_DELETE
                + " = 0";
        return query(selection, null, null);
    }

    public int getDownloadingCount(int classId) {
        String selection = DownloadTable.STATE + " != " + FileDownloader.FINISH + " AND "
                + DownloadTable.CLASSID + " = " + classId + " AND " + DownloadTable.IS_DELETE
                + " = 0";
        return getCount(selection, null);
    }

    /**
     * 获取已下载完成的任务列表
     * 
     * @return
     */
    public List<DownloadFile> getDownloadedFiles(int classId) {
        String selection = DownloadTable.STATE + " = ? AND " + DownloadTable.CLASSID + " = ? AND "
                + DownloadTable.IS_DELETE + " = ? ";
        String[] selectionArgs = {
                String.valueOf(FileDownloader.FINISH), String.valueOf(classId), String.valueOf(0)
        };
        return query(selection, selectionArgs, null);
    }

    public int getDownloadedCount(int classId) {
        String selection = DownloadTable.STATE + " = ? AND " + DownloadTable.CLASSID + " = ? AND "
                + DownloadTable.IS_DELETE + " = ? ";
        String[] selectionArgs = {
                String.valueOf(FileDownloader.FINISH), String.valueOf(classId), String.valueOf(0)
        };
        return getCount(selection, selectionArgs);
    }

    /**
     * 移除所有已下载完毕的数据（非删除条目）
     * 
     * @return
     */
    public long setAllHasDownloadedFileRemove(int classId) {
        String selection = DownloadTable.STATE + " = ? AND " + DownloadTable.CLASSID + " = ? ";
        String[] selectionArgs = {
                String.valueOf(FileDownloader.FINISH), String.valueOf(classId)
        };
        ContentValues cv = new ContentValues();
        cv.put(DownloadTable.IS_DELETE, 1);
        return update(cv, selection, selectionArgs);
    }

    /**
     * 移除已下载完毕的数据（非删除条目）
     * 
     * @return
     */
    public long setHasDownloadedFileRemove(String key) {
        String selection = DownloadTable.STATE + " = ? AND " + DownloadTable.KEY + " = ? ";
        String[] selectionArgs = {
                String.valueOf(FileDownloader.FINISH), key
        };
        ContentValues cv = new ContentValues();
        cv.put(DownloadTable.IS_DELETE, 1);
        return update(cv, selection, selectionArgs);
    }

    public long deleteAllDownloadedFile(int classId) {
        String selection = DownloadTable.STATE + " = ? AND " + DownloadTable.CLASSID + " = ? ";
        String[] selectionArgs = {
                String.valueOf(FileDownloader.FINISH), String.valueOf(classId)
        };
        return delete(selection, selectionArgs);
    }

    /**
     * 下载完成后更新下载完成时间
     * 
     * @param id 文件ID
     * @param downloadCompleteTime 下载完成的时间戳
     * @return
     */
    public long updateDownloadFinishTime(long id, long downloadCompleteTime) {
        String selection = DownloadTable._ID + " = ? ";
        String[] selectionArgs = {
            String.valueOf(id)
        };
        ContentValues cv = new ContentValues();
        cv.put(DownloadTable.EXT8, String.valueOf(downloadCompleteTime));
        return update(cv, selection, selectionArgs);
    }

    /**
     * 更新应用的自动下载标识
     * 
     * @param key
     * @param autoDownloadFlag
     * @return
     */
    public long updateAutoDownloadFlag(String key, int autoDownloadFlag) {
        String selection = DownloadTable.KEY + " = ? ";
        String[] selectionArgs = {
            key
        };
        ContentValues cv = new ContentValues();
        cv.put(DownloadTable.EXT9, autoDownloadFlag);
        long id = update(cv, selection, selectionArgs);
        return id;
    }
}
